-------------------模块区-------------------
local dx_mqtt = require("dx_mqtt")
local dx_map = require("dx_map")
local dx_queue = require("dx_queue")
local dx_json = require("dx_json")
local log = require("dx_logger")
local os_util = require("os_util")
local mqtt_service = require("mqtt_service")
local config = require("config")

-------------------变量区-------------------
local mqtt_common = {}
-- 初始化连接状态为true，如果接收到quit消息则赋值为false
local running = true

-------------------函数区-------------------
-- 根据topic截取字符串获取对应的方法
local function get_method(topic)
    return string.sub(topic, #topic - string.find(string.reverse(topic), "/") + 2, #topic)
end

-- 处理订阅消息
local function callback(topic, payload)
    if payload == "quit" then
        log.warn("[mqtt]链接掉线")
        running = false
        return 0
    end

    dx_map.set(_G_map, "mqtt_dog", "Y")

    local ret = mqtt_service[get_method(topic)](payload)
    if not ret then
        if topic ~= mqtt_service.publish.EVENT_TOPIC_LOG then
            -- 避免日志上报陷入循环
            log.error("消息处理异常topic：" .. topic .. "，payload：" .. payload)
        end
    end
end



-- 创建client
function mqtt_common.create_client(args)
    _G.mqtt_client = dx_mqtt.client.create(args.host, args.port, callback)
    log.info("[mqtt_client]创建完成")
end



-- 建立mqtt连接
function mqtt_common.create_connect(args)
    dx_map.set(_G_map, "mqtt_dog", "Y")
    local connect_error = mqtt_client:connect(args.id)
    while connect_error ~= nil do
        os.execute("sleep " .. 1)
        connect_error = mqtt_client:connect(args.id)

        -- 等待建立mqtt连接也要喂狗
        dx_map.set(_G_map, "mqtt_dog", "Y")
    end
    dx_map.set(_G_map, "mqtt_connect_ing", "Y")
    -- 连接成功，上送设备信息
    -- mqtt_service.connect()
    log.info("[mqtt链接]初始化完成")
end



-- 添加订阅
function mqtt_common.create_subscribe()
    mqtt_client:subscribe(mqtt_service.subscribe)
    log.info("[mqtt消息订阅]初始化完成")
end



-- mqtt保活逻辑
function mqtt_common.Keep_alive(args)
    local error_message = nil
    running = true

    while (error_message == nil and running) do
        error_message = mqtt_client:handler()
        if error_message == nil then

            -- 监听处理mqtt线程输入队列
            local mqtt_msg = dx_queue.pop(mqtt_queue, 50)
            if mqtt_msg ~= nil then
                -- 数据格式为json 示例：{"topic":"","data":""}
                local mqtt_req = dx_json.decode(mqtt_msg)
                callback(mqtt_req.topic, mqtt_req.data)
            end
            os_util.sleep(0.01)
            -- 网络灯打开
            if not config.get("mqtt_con_status") then
                config.set("mqtt_con_status", "true")
            end
        end
        dx_map.set(_G_map, "mqtt_dog", "Y")
    end
    return error_message
end


function mqtt_common.error(error_message, args)
    -- mqtt断连,网络灯关闭
    config.set("mqtt_con_status","flase")
    -- mqtt服务停止，判断是否正常停止
    if (error_message == nil) then
        mqtt_client:unsubscribe({args.topic_s})
        mqtt_client:destroy()
        log.info("mqtt服务停止，订阅&链接已释放")
        return false
    else
        log.error("mqtt通道异常：", error_message)
        return true
    end
end

function mqtt_common.mqtt_init()
    -- 无法将mqtt通道指定给全局map，所以需要监听堵塞队列进行消费发送消息请求
    _G._G_map = _G["_G_map"]
    _G.mqtt_queue = dx_map.get(_G_map, "mqtt_queue")
    -- 全局sqlite实例
    _G.sqlite_client = dx_map.get(_G_map, "sqlite_client")

    -- mqtt链接信息
    local args = {
        host = config.get("mqtt_mqttAddr"),
        port = config.get("mqtt_port"),
        id = config.get("mqtt_clientId"),
        debug = true
    }
    local flag = true
    log.info("mqtthost信息：", args.host)
    while flag do
        mqtt_common.create_client(args)
        mqtt_common.create_connect(args)
        mqtt_common.create_subscribe()
        local error_message = mqtt_common.Keep_alive(args)
        flag = mqtt_common.error(error_message, args)
        os_util.sleep(2)
        -- 等待建立mqtt连接也要喂狗
        dx_map.set(_G_map, "mqtt_dog", "Y")
    end
end

-------------------主流程-------------------
log.info("mqtthost信息：adfadfadfad")
mqtt_common.mqtt_init()

return mqtt_common
